/* private */ var $mMinorEdit, $mRedirectedFrom;
/* private */ var $mTouched, $mFileCache, $mTitle;
/* private */ var $mId, $mTable;
-
+
function Article( &$title ) {
$this->mTitle =& $title;
$this->clear();
}
-
+
/* private */ function clear()
{
$this->mContentLoaded = false;
}
return $text;
}
-
+
/* static */ function compressRevisionText( &$text ) {
global $wgCompressRevisions;
if( !$wgCompressRevisions ) {
$text = gzdeflate( $text );
return 'gzip';
}
-
+
# Returns the text associated with a "link" type old table row
/* static */ function followLink( $link ) {
# Split the link into fields and values
global $wgLoadBalancer;
$fname = 'fetchFromLocation';
wfProfileIn( $fname );
-
+
$p = strpos( $location, ':' );
if ( $p === false ) {
wfProfileOut( $fname );
case 'mysql':
# MySQL locations are specified by mysql://<machineID>/<dbname>/<tblname>/<index>
# Machine ID 0 is the current connection
- if ( preg_match( '/^mysql:\/\/(\d+)\/([A-Za-z_]+)\/([A-Za-z_]+)\/([A-Za-z_]+)$/',
+ if ( preg_match( '/^mysql:\/\/(\d+)\/([A-Za-z_]+)\/([A-Za-z_]+)\/([A-Za-z_]+)$/',
$location, $matches ) ) {
$machineID = $matches[1];
$dbName = $matches[2];
} else {
# Alternate connection
$db =& $wgLoadBalancer->getConnection( $machineID );
-
+
if ( array_key_exists( $machineId, $wgKnownMysqlServers ) ) {
# Try to open, return false on failure
$params = $wgKnownDBServers[$machineId];
- $db = Database::newFromParams( $params['server'], $params['user'], $params['password'],
+ $db = Database::newFromParams( $params['server'], $params['user'], $params['password'],
$dbName, 1, false, true, true );
}
}
}
}
}
-
+
# This function returns the text of a section, specified by a number ($section).
- # A section is text under a heading like == Heading == or <h1>Heading</h1>, or
+ # A section is text under a heading like == Heading == or <h1>Heading</h1>, or
# the first section before any such heading (section 0).
#
# If a section contains subsections, these are also returned.
#
function getSection($text,$section) {
-
+
# strip NOWIKI etc. to avoid confusion (true-parameter causes HTML
# comments to be stripped as well)
$striparray=array();
$headline=$secs[$section*2-1];
preg_match( '/^(=+).*?=+|^<h([1-6]).*?' . '>.*?<\/h[1-6].*?' . '>/mi',$headline,$matches);
$hlevel=$matches[1];
-
+
# translate wiki heading into level
if(strpos($hlevel,'=')!==false) {
- $hlevel=strlen($hlevel);
+ $hlevel=strlen($hlevel);
}
-
+
$rv=$headline. $secs[$section*2];
$count=$section+1;
-
+
$break=false;
while(!empty($secs[$count*2-1]) && !$break) {
-
+
$subheadline=$secs[$count*2-1];
preg_match( '/^(=+).*?=+|^<h([1-6]).*?' . '>.*?<\/h[1-6].*?' . '>/mi',$subheadline,$matches);
$subhlevel=$matches[1];
if(strpos($subhlevel,'=')!==false) {
- $subhlevel=strlen($subhlevel);
+ $subhlevel=strlen($subhlevel);
}
if($subhlevel > $hlevel) {
$rv.=$subheadline.$secs[$count*2];
$break=true;
}
$count++;
-
+
}
}
# reinsert stripped tags
return $rv;
}
-
+
# Load the revision (including cur_text) into this object
function loadContent( $noredir = false )
if ( $this->mContentLoaded ) return;
$fname = 'Article::loadContent';
-
- # Pre-fill content with error message so that if something
+
+ # Pre-fill content with error message so that if something
# fails we'll have something telling us what we intended.
- $t = $this->mTitle->getPrefixedText();
- if ( isset( $oldid ) ) {
- $oldid = IntVal( $oldid );
+ $t = $this->mTitle->getPrefixedText();
+ if ( isset( $oldid ) ) {
+ $oldid = IntVal( $oldid );
$t .= ",oldid={$oldid}";
- }
- if ( isset( $redirect ) ) {
- $redirect = ($redirect == 'no') ? 'no' : 'yes';
- $t .= ",redirect={$redirect}";
- }
+ }
+ if ( isset( $redirect ) ) {
+ $redirect = ($redirect == 'no') ? 'no' : 'yes';
+ $t .= ",redirect={$redirect}";
+ }
$this->mContent = wfMsg( 'missingarticle', $t );
-
+
if ( ! $oldid ) { # Retrieve current version
$id = $this->getID();
if ( 0 == $id ) return;
"FROM cur WHERE cur_id={$id}";
wfDebug( "$sql\n" );
$res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) {
- return;
+ if ( 0 == wfNumRows( $res ) ) {
+ return;
}
$s = wfFetchObject( $res );
# Gotta hand redirects to special pages differently:
# Fill the HTTP response "Location" header and ignore
# the rest of the page we're on.
-
+
if ( $rt->getInterwiki() != '' ) {
$wgOut->redirect( $rt->getFullURL() ) ;
return;
$sql = 'SELECT cur_text,cur_timestamp,cur_user,cur_user_text,cur_comment,' .
"cur_counter,cur_restrictions,cur_touched FROM cur WHERE cur_id={$rid}";
$res = wfQuery( $sql, DB_READ, $fname );
-
+
if ( 0 != wfNumRows( $res ) ) {
$this->mRedirectedFrom = $this->mTitle->getPrefixedText();
$this->mTitle = $rt;
return $this->mContent;
}
$this->mContent = false;
-
+
$fname = 'Article::loadContent';
-
+
if ( ! $oldid ) { # Retrieve current version
$id = $this->getID();
if ( 0 == $id ) {
'cur_text,cur_timestamp,cur_user,cur_counter,cur_restrictions,cur_touched ' .
"FROM cur WHERE cur_id={$id}";
$res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) {
- return false;
+ if ( 0 == wfNumRows( $res ) ) {
+ return false;
}
$s = wfFetchObject( $res );
$sql = 'SELECT cur_text,cur_timestamp,cur_user,' .
"cur_counter,cur_restrictions,cur_touched FROM cur WHERE cur_id={$rid}";
$res = wfQuery( $sql, DB_READ, $fname );
-
+
if ( 0 != wfNumRows( $res ) ) {
$this->mRedirectedFrom = $this->mTitle->getPrefixedText();
$this->mTitle = $rt;
$sql = "SELECT old_text,old_timestamp,old_user,old_flags FROM $oldtable " .
"WHERE old_id={$oldid}";
$res = wfQuery( $sql, DB_READ, $fname );
- if ( 0 == wfNumRows( $res ) ) {
- return false;
+ if ( 0 == wfNumRows( $res ) ) {
+ return false;
}
$s = wfFetchObject( $res );
function isCountable( $text )
{
global $wgUseCommaCount, $wgMwRedir;
-
+
if ( 0 != $this->mTitle->getNamespace() ) { return 0; }
if ( $wgMwRedir->matchStart( $text ) ) { return 0; }
$token = ($wgUseCommaCount ? ',' : '[[' );
$fname = 'Article::getContributors';
# XXX: this is expensive; cache this info somewhere.
-
+
$title = $this->mTitle;
$contribs = array();
' FROM old LEFT JOIN user ON old.old_user = user.user_id ' .
' WHERE old.old_namespace = ' . $title->getNamespace() .
' AND old.old_title = "' . $title->getDBkey() . '"' .
- ' AND old.old_user != ' . $this->getUser() .
- ' GROUP BY old.old_user ' .
+ ' AND old.old_user != ' . $this->getUser() .
+ ' GROUP BY old.old_user ' .
' ORDER BY timestamp DESC ';
if ($limit > 0) {
}
$res = wfQuery($sql, DB_READ, $fname);
-
+
while ( $line = wfFetchObject( $res ) ) {
$contribs[] = array($line->old_user, $line->old_user_text, $line->user_real_name);
}
-
+
wfFreeResult($res);
-
+
return $contribs;
}
-
+
# This is the default action of the script: just view the page of
# the given title.
{
global $wgUser, $wgOut, $wgLang, $wgRequest;
global $wgLinkCache, $IP, $wgEnableParserCache;
-
+
$fname = 'Article::view';
wfProfileIn( $fname );
return;
}
}
-
+
# Should the parser cache be used?
if ( $wgEnableParserCache && intval($wgUser->getOption( 'stubthreshold' )) == 0 && empty( $oldid ) ) {
$pcache = true;
} else {
$pcache = false;
}
-
+
$outputDone = false;
if ( $pcache ) {
if ( $wgOut->tryParserCache( $this, $wgUser ) ) {
if ( !$outputDone ) {
$text = $this->getContent( false ); # May change mTitle by following a redirect
-
+
# Another whitelist check in case oldid or redirects are altering the title
if ( !$this->mTitle->userCanRead() ) {
$wgOut->loginToUse();
$wgOut->output();
exit;
}
-
+
# We're looking at an old revision
'redirect=no' );
$s = wfMsg( 'redirectedfrom', $redir );
$wgOut->setSubtitle( $s );
-
- # Can't cache redirects
+
+ # Can't cache redirects
$pcache = false;
}
# wrap user css and user js in pre and don't parse
# XXX: use $this->mTitle->usCssJsSubpage() when php is fixed/ a workaround is found
- if (
- $this->mTitle->getNamespace() == Namespace::getUser() &&
+ if (
+ $this->mTitle->getNamespace() == Namespace::getUser() &&
preg_match('/\\/[\\w]+\\.(css|js)$/', $this->mTitle->getDBkey())
) {
$wgOut->addWikiText( wfMsg('clearyourcache'));
}
}
$wgOut->setPageTitle( $this->mTitle->getPrefixedText() );
-
+
# Add link titles as META keywords
$wgOut->addMetaTags() ;
{
global $wgOut, $wgUser, $wgLinkCache, $wgMwRedir;
global $wgUseSquid, $wgDeferredUpdateList, $wgInternalServer, $wgIsPg, $wgIsMySQL;
-
+
$fname = 'Article::insertNewArticle';
$this->mCountAdjustment = $this->isCountable( $text );
$won = wfInvertTimestamp( $now );
wfSeedRandom();
$rand = number_format( mt_rand() / mt_getrandmax(), 12, '.', '' );
-
+
if ($wgIsPg) {
$cur_id_column="cur_id,";
$cur_id=wfGetSQL(""," nextval('cur_cur_id_seq')");
Article::onArticleCreate( $this->mTitle );
RecentChange::notifyNew( $now, $this->mTitle, $isminor, $wgUser, $summary );
-
- if ($watchthis) {
- if(!$this->mTitle->userIsWatching()) $this->watch();
+
+ if ($watchthis) {
+ if(!$this->mTitle->userIsWatching()) $this->watch();
} else {
if ( $this->mTitle->userIsWatching() ) {
$this->unwatch();
}
}
-
+
# The talk page isn't in the regular link tables, so we need to update manually:
$talkns = $ns ^ 1; # talk -> normal; normal -> talk
$sql = "UPDATE cur set cur_touched='$now' WHERE cur_namespace=$talkns AND cur_title='" . wfStrencode( $ttl ) . "'";
wfQuery( $sql, DB_WRITE );
-
+
# standard deferred updates
$this->editUpdates( $text );
/* Side effects: loads last edit */
function getTextOfLastEditWithSectionReplacedOrAdded($section, $text, $summary = ''){
$this->loadLastEdit();
- $oldtext = $this->getContent( true );
+ $oldtext = $this->getContent( true );
if ($section != '') {
if($section=='new') {
if($summary) $subject="== {$summary} ==\n\n";
$secs=preg_split('/(^=+.*?=+|^<h[1-6].*?' . '>.*?<\/h[1-6].*?' . '>)/mi',
$oldtext,-1,PREG_SPLIT_DELIM_CAPTURE);
$secs[$section*2]=$text."\n\n"; // replace with edited
-
+
# section 0 is top (intro) section
- if($section!=0) {
-
+ if($section!=0) {
+
# headline of old section - we need to go through this section
# to determine if there are any subsections that now need to
# be erased, as the mother section has been replaced with
$headline=$secs[$section*2-1];
preg_match( '/^(=+).*?=+|^<h([1-6]).*?' . '>.*?<\/h[1-6].*?' . '>/mi',$headline,$matches);
$hlevel=$matches[1];
-
+
# determine headline level for wikimarkup headings
if(strpos($hlevel,'=')!==false) {
- $hlevel=strlen($hlevel);
+ $hlevel=strlen($hlevel);
}
-
+
$secs[$section*2-1]=''; // erase old headline
$count=$section+1;
$break=false;
while(!empty($secs[$count*2-1]) && !$break) {
-
+
$subheadline=$secs[$count*2-1];
preg_match(
'/^(=+).*?=+|^<h([1-6]).*?' . '>.*?<\/h[1-6].*?' . '>/mi',$subheadline,$matches);
$subhlevel=$matches[1];
if(strpos($subhlevel,'=')!==false) {
- $subhlevel=strlen($subhlevel);
+ $subhlevel=strlen($subhlevel);
}
if($subhlevel > $hlevel) {
// erase old subsections
$break=true;
}
$count++;
-
+
}
-
+
}
$text=join('',$secs);
# reinsert the stuff that we stripped out earlier
- $text=$parser->unstrip($text,$striparray);
- $text=$parser->unstripNoWiki($text,$striparray);
+ $text=$parser->unstrip($text,$striparray);
+ $text=$parser->unstripNoWiki($text,$striparray);
}
-
+
}
return $text;
}
$fname = 'Article::updateArticle';
if ( $this->mMinorEdit ) { $me1 = 1; } else { $me1 = 0; }
- if ( $minor && $wgUser->getID() ) { $me2 = 1; } else { $me2 = 0; }
+ if ( $minor && $wgUser->getID() ) { $me2 = 1; } else { $me2 = 0; }
if ( preg_match( "/^((" . $wgMwRedir->getBaseRegex() . ')[^\\n]+)/i', $text, $m ) ) {
$redir = 1;
$text = $m[1] . "\n"; # Remove all content but redirect
else { $redir = 0; }
$text = $this->preSaveTransform( $text );
-
+
# Update article, but only if changed.
if( $wgDBtransactions ) {
"WHERE cur_id=" . $this->getID() .
" AND cur_timestamp='" . $this->getTimestamp() . "'";
$res = wfQuery( $sql, DB_WRITE, $fname );
-
+
if( wfAffectedRows() == 0 ) {
/* Belated edit conflict! Run away!! */
return false;
# This overwrites $oldtext if revision compression is on
$flags = Article::compressRevisionText( $oldtext );
-
+
$oldtable=$wgIsPg?'"old"':'old';
if ($wgIsPg) {
$oldtable='"old"';
$oldid = $wgIsPg?$old_id:wfInsertId( $res );
$bot = (int)($wgUser->isBot() || $forceBot);
- RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary,
+ RecentChange::notifyEdit( $now, $this->mTitle, $me2, $wgUser, $summary,
$oldid, $this->getTimestamp(), $bot );
Article::onArticleEdit( $this->mTitle );
}
$sql = 'COMMIT';
wfQuery( $sql, DB_WRITE );
}
-
- if ($watchthis) {
- if (!$this->mTitle->userIsWatching()) $this->watch();
+
+ if ($watchthis) {
+ if (!$this->mTitle->userIsWatching()) $this->watch();
} else {
if ( $this->mTitle->userIsWatching() ) {
$this->unwatch();
}
# standard deferred updates
$this->editUpdates( $text );
-
-
+
+
$urls = array();
# Template namespace
# Purge all articles linking here
}
}
}
-
+
# Squid updates
if ( $wgUseSquid ) {
$urls = array_merge( $urls, $this->mTitle->getSquidURLs() );
$wgLinkCache->preFill( $this->mTitle );
$wgLinkCache->clear();
- # Now update the link cache by parsing the text
+ # Now update the link cache by parsing the text
$wgOut = new OutputPage();
$wgOut->addWikiText( $text );
if ( $confirm ) {
- $sql = "UPDATE cur SET cur_touched='" . wfTimestampNow() . "'," .
- "cur_restrictions='{$limit}' WHERE cur_id={$id}";
- wfQuery( $sql, DB_WRITE, 'Article::protect' );
+ $sql = "UPDATE cur SET cur_touched='" . wfTimestampNow() . "'," .
+ "cur_restrictions='{$limit}' WHERE cur_id={$id}";
+ wfQuery( $sql, DB_WRITE, 'Article::protect' );
- $log = new LogPage( wfMsg( 'protectlogpage' ), wfMsg( 'protectlogtext' ) );
- if ( $limit === "" ) {
- $log->addEntry( wfMsg( 'unprotectedarticle', $this->mTitle->getPrefixedText() ), $reason );
- } else {
- $log->addEntry( wfMsg( 'protectedarticle', $this->mTitle->getPrefixedText() ), $reason );
- }
- $wgOut->redirect( $this->mTitle->getFullURL() );
+ $log = new LogPage( wfMsg( 'protectlogpage' ), wfMsg( 'protectlogtext' ) );
+ if ( $limit === "" ) {
+ $log->addEntry( wfMsg( 'unprotectedarticle', $this->mTitle->getPrefixedText() ), $reason );
+ } else {
+ $log->addEntry( wfMsg( 'protectedarticle', $this->mTitle->getPrefixedText() ), $reason );
+ }
+ $wgOut->redirect( $this->mTitle->getFullURL() );
return;
} else {
$reason = htmlspecialchars( wfMsg( 'protectreason' ) );
$protcom = '';
if ( $limit === '' ) {
+ $wgOut->setPageTitle( wfMsg( 'confirmunprotect' ) );
$wgOut->setSubtitle( wfMsg( 'unprotectsub', $sub ) );
$wgOut->addWikiText( wfMsg( 'confirmunprotecttext' ) );
$check = htmlspecialchars( wfMsg( 'confirmunprotect' ) );
$protcom = htmlspecialchars( wfMsg( 'unprotectcomment' ) );
$formaction = $this->mTitle->escapeLocalURL( 'action=unprotect' . $par );
} else {
+ $wgOut->setPageTitle( wfMsg( 'confirmprotect' ) );
$wgOut->setSubtitle( wfMsg( 'protectsub', $sub ) );
$wgOut->addWikiText( wfMsg( 'confirmprotecttext' ) );
$check = htmlspecialchars( wfMsg( 'confirmprotect' ) );
return $this->protect( '' );
}
- # UI entry point for page deletion
+ # UI entry point for page deletion
function delete()
{
global $wgUser, $wgOut, $wgMessageCache, $wgRequest, $wgIsPg;
$fname = 'Article::delete';
$confirm = $wgRequest->getBool( 'wpConfirm' ) && $wgRequest->wasPosted();
$reason = $wgRequest->getText( 'wpReason' );
-
+
# This code desperately needs to be totally rewritten
-
+
# Check permissions
if ( ( ! $wgUser->isSysop() ) ) {
$wgOut->sysopRequired();
$text = Article::getRevisionText( $old );
$blanked = true;
}
-
+
}
-
- $length=strlen($text);
-
+
+ $length=strlen($text);
+
# this should not happen, since it is not possible to store an empty, new
# page. Let's insert a standard text in case it does, though
- if($length == 0 && $reason === '') {
+ if($length == 0 && $reason === '') {
$reason = wfMsg('exblank');
}
-
+
if($length < 500 && $reason === '') {
-
+
# comment field=255, let's grep the first 150 to have some user
# space left
$text=substr($text,0,150);
$reason=wfMsg('exbeforeblank') . " '".$text;
}
if($length>150) { $reason .= '...'; } # we've only pasted part of the text
- $reason.="'";
+ $reason.="'";
}
}
return $this->confirmDelete( '', $reason );
}
-
+
# Output deletion confirmation dialog
function confirmDelete( $par, $reason )
{
global $wgOut;
wfDebug( "Article::confirmDelete\n" );
-
+
$sub = htmlspecialchars( $this->mTitle->getPrefixedText() );
$wgOut->setSubtitle( wfMsg( 'deletesub', $sub ) );
$wgOut->setRobotpolicy( 'noindex,nofollow' );
$wgOut->addWikiText( wfMsg( 'confirmdeletetext' ) );
$formaction = $this->mTitle->escapeLocalURL( 'action=delete' . $par );
-
+
$confirm = htmlspecialchars( wfMsg( 'confirm' ) );
$check = htmlspecialchars( wfMsg( 'confirmcheck' ) );
$delcom = htmlspecialchars( wfMsg( 'deletecomment' ) );
$fname = 'Article::doDelete';
wfDebug( "$fname\n" );
- if ( $this->doDeleteArticle( $reason ) ) {
+ if ( $this->doDeleteArticle( $reason ) ) {
$deleted = $this->mTitle->getPrefixedText();
$wgOut->setPagetitle( wfMsg( 'actioncomplete' ) );
$u = new SiteStatsUpdate( 0, 1, -$this->isCountable( $this->getContent( true ) ) );
array_push( $wgDeferredUpdateList, $u );
-
+
$linksTo = $this->mTitle->getLinksTo();
# Squid purging
if ( $wgUseSquid ) {
- $urls = array(
+ $urls = array(
$this->mTitle->getInternalURL(),
- $this->mTitle->getInternalURL( 'history' )
+ $this->mTitle->getInternalURL( 'history' )
);
foreach ( $linksTo as $linkTo ) {
$urls[] = $linkTo->getInternalURL();
$sql = "DELETE FROM old WHERE old_namespace={$ns} AND " .
"old_title='{$t}'";
wfQuery( $sql, DB_WRITE, $fname );
-
+
$sql = "DELETE FROM recentchanges WHERE rc_namespace={$ns} AND " .
"rc_title='{$t}'";
wfQuery( $sql, DB_WRITE, $fname );
$t = wfStrencode( $this->mTitle->getPrefixedDBkey() );
Article::onArticleDelete( $this->mTitle );
-
+
$sql = 'INSERT INTO brokenlinks (bl_from,bl_to) VALUES ';
$first = true;
if ( ! $first ) { $sql .= ','; }
$first = false;
# Get article ID. Efficient because it was loaded into the cache by getLinksTo().
- $linkID = $titleObj->getArticleID();
+ $linkID = $titleObj->getArticleID();
$sql .= "({$linkID},'{$t}')";
}
if ( ! $first ) {
$sql = "DELETE FROM brokenlinks WHERE bl_from={$id}";
wfQuery( $sql, DB_WRITE, $fname );
-
+
$sql = "DELETE FROM categorylinks WHERE cl_from={$id}";
wfQuery( $sql, DB_WRITE, $fname );
-
+
$log = new LogPage( wfMsg( 'dellogpage' ), wfMsg( 'dellogpagetext' ) );
$art = $this->mTitle->getPrefixedText();
$log->addEntry( wfMsg( 'deletedarticle', $art ), $reason );
$wgOut->readOnlyPage( $this->getContent( true ) );
return;
}
-
+
# Enhanced rollback, marks edits rc_bot=1
$bot = $wgRequest->getBool( 'bot' );
-
+
# Replace all this user's current edits with the next one down
$tt = wfStrencode( $this->mTitle->getDBKey() );
$n = $this->mTitle->getNamespace();
-
+
# Get the last editor
$sql = 'SELECT cur_id,cur_user,cur_user_text,cur_comment ' .
"FROM cur WHERE cur_title='{$tt}' AND cur_namespace={$n}";
$ut = wfStrencode( $s->cur_user_text );
$uid = $s->cur_user;
$pid = $s->cur_id;
-
+
$from = str_replace( '_', ' ', $wgRequest->getVal( 'from' ) );
if( $from != $s->cur_user_text ) {
$wgOut->setPageTitle(wfmsg('rollbackfailed'));
}
return;
}
-
+
# Get the last edit not by this guy
$use_index=$wgIsMySQL?"USE INDEX (name_title_timestamp)":"";
return;
}
$s = wfFetchObject( $res );
-
+
if ( $bot ) {
# Mark all reverted edits as bot
$sql = 'UPDATE recentchanges SET rc_bot=1 WHERE ' .
Article::onArticleEdit( $this->mTitle );
$wgOut->returnToMain( false );
}
-
+
# Do standard deferred updates after page view
$id = $this->getID();
$title = $this->mTitle->getPrefixedDBkey();
$shortTitle = $this->mTitle->getDBkey();
-
+
$adj = $this->mCountAdjustment;
if ( 0 != $id ) {
global $wgParser, $wgUser;
return $wgParser->preSaveTransform( $text, $this->mTitle, $wgUser, ParserOptions::newFromUser( $wgUser ) );
}
-
+
/* Caching functions */
# checkLastModified returns true if it has taken care of all
$cache->loadFromFileCache();
return true;
} else {
- wfDebug( " tryFileCache() - starting buffer\n" );
+ wfDebug( " tryFileCache() - starting buffer\n" );
ob_start( array(&$cache, 'saveToFileCache' ) );
}
} else {
function isFileCacheable() {
global $wgUser, $wgUseFileCache, $wgShowIPinHeader, $wgRequest;
extract( $wgRequest->getValues( 'action', 'oldid', 'diff', 'redirect', 'printable' ) );
-
+
return $wgUseFileCache
and (!$wgShowIPinHeader)
and ($this->getID() != 0)
and (!isset($printable))
and (!$this->mRedirectedFrom);
}
-
+
# Loads cur_touched and returns a value indicating if it should be used
function checkTouched() {
$id = $this->getID();
$dbkey = $this->mTitle->getDBkey();
$encDbKey = wfStrencode( $dbkey );
$timestamp = wfTimestampNow();
-
+
# Save to history
$oldtable=$wgIsPg?'"old"':'old';
$sql = "INSERT INTO $oldtable (old_namespace,old_title,old_text,old_comment,old_user,old_user_text,old_timestamp,inverse_timestamp)
SELECT cur_namespace,cur_title,cur_text,cur_comment,cur_user,cur_user_text,cur_timestamp,99999999999999-cur_timestamp
FROM cur WHERE cur_namespace=$ns AND cur_title='$encDbKey'";
wfQuery( $sql, DB_WRITE );
-
+
# Use the affected row count to determine if the article is new
$numRows = wfAffectedRows();
$id = intval( $id );
global $wgHitcounterUpdateFreq;
- if( $wgHitcounterUpdateFreq <= 1 ){ //
+ if( $wgHitcounterUpdateFreq <= 1 ){ //
wfQuery('UPDATE cur SET cur_counter = cur_counter + 1 ' .
'WHERE cur_id = '.$id, DB_WRITE);
return;
}
# Not important enough to warrant an error page in case of failure
- $oldignore = wfIgnoreSQLErrors( true );
+ $oldignore = wfIgnoreSQLErrors( true );
wfQuery("INSERT INTO hitcounter (hc_id) VALUES ({$id})", DB_WRITE);
$res = wfQuery('SELECT COUNT(*) as n FROM hitcounter', DB_WRITE);
$row = wfFetchObject( $res );
$rown = intval( $row->n );
- if( $rown >= $wgHitcounterUpdateFreq ){
+ if( $rown >= $wgHitcounterUpdateFreq ){
wfProfileIn( 'Article::incViewCount-collect' );
$old_user_abort = ignore_user_abort( true );
}
# The onArticle*() functions are supposed to be a kind of hooks
- # which should be called whenever any of the specified actions
- # are done.
+ # which should be called whenever any of the specified actions
+ # are done.
#
- # This is a good place to put code to clear caches, for instance.
+ # This is a good place to put code to clear caches, for instance.
- # This is called on page move and undelete, as well as edit
+ # This is called on page move and undelete, as well as edit
/* static */ function onArticleCreate($title_obj){
global $wgUseSquid, $wgDeferredUpdateList;
$titles = $title_obj->getBrokenLinksTo();
-
- # Purge squid
+
+ # Purge squid
if ( $wgUseSquid ) {
$urls = $title_obj->getSquidURLs();
foreach ( $titles as $linkTitle ) {
/* static */ function onArticleEdit($title_obj){
LinkCache::linksccClearPage( $title_obj->getArticleID() );
}
+
+ # Info about this page
+
+ function info()
+ {
+ global $wgUser, $wgTitle, $wgOut, $wgLang;
+
+ $basenamespace = $wgTitle->getNamespace() & (~1);
+ $cur_clause = "cur_title='".$wgTitle->getDBkey()."' AND cur_namespace=".$basenamespace;
+ $old_clause = "old_title='".$wgTitle->getDBkey()."' AND old_namespace=".$basenamespace;
+ $wl_clause = "wl_title='".$wgTitle->getDBkey()."' AND wl_namespace=".$basenamespace;
+ $fullTitle = $wgTitle->makeName($basenamespace, $wgTitle->getDBKey());
+ $wgOut->setPagetitle( $fullTitle );
+ $wgOut->setSubtitle( wfMsg( "infosubtitle" ));
+
+ # first, see if the page exists at all.
+ $sql = "SELECT COUNT(*) FROM cur WHERE ".$cur_clause;
+ $exists = wfSingleQuery( $sql , DB_READ );
+ if ($exists < 1) {
+ $wgOut->addHTML( wfMsg("noarticletext") );
+ } else {
+ $sql = "SELECT COUNT(*) FROM watchlist WHERE ".$wl_clause;
+ $wgOut->addHTML( "<ul><li>" . wfMsg("numwatchers") . wfSingleQuery( $sql, DB_READ ) . "</li>" );
+ $sql = "SELECT COUNT(*) FROM old WHERE ".$old_clause;
+ $old = wfSingleQuery( $sql, DB_READ );
+ $wgOut->addHTML( "<li>" . wfMsg("numedits") . ($old + 1) . "</li>");
+
+ # to find number of distinct authors, we need to do some
+ # funny stuff because of the cur/old table split:
+ # - first, find the name of the 'cur' author
+ # - then, find the number of *other* authors in 'old'
+
+ # find 'cur' author
+ $sql = "SELECT cur_user_text FROM cur WHERE ".$cur_clause;
+ $cur_author = wfSingleQuery( $sql, DB_READ );
+
+ # find number of 'old' authors excluding 'cur' author
+ $sql = "SELECT COUNT(DISTINCT old_user_text) FROM old WHERE ".$old_clause
+ ." AND old_user_text<>'" . $cur_author . "'";
+ $authors = wfSingleQuery( $sql, DB_READ ) + 1;
+
+ # now for the Talk page ...
+ $cur_clause = "cur_title='".$wgTitle->getDBkey()."' AND cur_namespace=".($basenamespace+1);
+ $old_clause = "old_title='".$wgTitle->getDBkey()."' AND old_namespace=".($basenamespace+1);
+
+ # does it exist?
+ $sql = "SELECT COUNT(*) FROM cur WHERE ".$cur_clause;
+ $exists = wfSingleQuery( $sql , DB_READ );
+
+ # number of edits
+ if ($exists > 0) {
+ $sql = "SELECT COUNT(*) FROM old WHERE ".$old_clause;
+ $old = wfSingleQuery( $sql, DB_READ );
+ $wgOut->addHTML( "<li>" . wfMsg("numtalkedits") . ($old + 1) . "</li>");
+ }
+ $wgOut->addHTML( "<li>" . wfMsg("numauthors") . $authors . "</li>" );
+
+ # number of authors
+ if ($exists > 0) {
+ $sql = "SELECT cur_user_text FROM cur WHERE ".$cur_clause;
+ $cur_author = wfSingleQuery( $sql, DB_READ );
+
+ $sql = "SELECT COUNT(DISTINCT old_user_text) FROM old WHERE "
+ .$old_clause." AND old_user_text<>'" . $cur_author . "'";
+ $authors = wfSingleQuery( $sql, DB_READ ) + 1;
+
+ $wgOut->addHTML( "<li>" . wfMsg("numtalkauthors") . $authors . "</li></ul>" );
+ }
+ }
+ }
}
?>
var $mSuppressQuickbar;
var $mOnloadHandler;
var $mDoNothing;
- var $mContainsOldMagic, $mContainsNewMagic;
+ var $mContainsOldMagic, $mContainsNewMagic;
var $mIsArticleRelated;
var $mParserOptions;
var $mShowFeedLinks = false;
var $mEnableClientCache = true;
-
+
function OutputPage()
{
$this->mHeaders = $this->mCookies = $this->mMetatags =
$this->mKeywords = $this->mLinktags = array();
$this->mHTMLtitle = $this->mPagetitle = $this->mBodytext =
$this->mRedirect = $this->mLastModified =
- $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy =
+ $this->mSubtitle = $this->mDebugtext = $this->mRobotpolicy =
$this->mOnloadHandler = "";
$this->mIsArticleRelated = $this->mIsarticle = $this->mPrintable = true;
$this->mSuppressQuickbar = $this->mPrintable = false;
function addKeyword( $text ) { array_push( $this->mKeywords, $text ); }
function addScript( $script ) { $this->mScripts .= $script; }
function getScript() { return $this->mScripts; }
-
+
function addLink( $linkarr ) {
# $linkarr should be an associative array of attributes. We'll escape on output.
array_push( $this->mLinktags, $linkarr );
# checkLastModified tells the client to use the client-cached page if
# possible. If sucessful, the OutputPage is disabled so that
# any future call to OutputPage->output() have no effect. The method
- # returns true iff cache-ok headers was sent.
+ # returns true iff cache-ok headers was sent.
function checkLastModified ( $timestamp )
{
global $wgLang, $wgCachePages, $wgUser;
$modsince = preg_replace( '/;.*$/', '', $_SERVER["HTTP_IF_MODIFIED_SINCE"] );
$ismodsince = wfUnix2Timestamp( strtotime( $modsince ) );
wfDebug( "-- client send If-Modified-Since: " . $modsince . "\n", false );
- wfDebug( "-- we might send Last-Modified : $lastmod\n", false );
+ wfDebug( "-- we might send Last-Modified : $lastmod\n", false );
if( ($ismodsince >= $timestamp ) and $wgUser->validateCache( $ismodsince ) ) {
# Make sure you're in a place you can leave when you call us!
global $action;
switch($action) {
case 'edit':
- return wfMsg('edit');
+ return wfMsg('edit');
case 'history':
return wfMsg('history_short');
case 'protect':
- return wfMsg('unprotect');
+ return wfMsg('protect');
case 'unprotect':
return wfMsg('unprotect');
case 'delete':
return wfMsg('unwatch');
case 'submit':
return wfMsg('preview');
+ case 'info':
+ return wfMsg('info_short');
default:
return '';
}
$this->mIsarticle = false;
}
}
- function setArticleFlag( $v ) {
- $this->mIsarticle = $v;
+ function setArticleFlag( $v ) {
+ $this->mIsarticle = $v;
if ( $v ) {
$this->mIsArticleRelated = $v;
}
{
return $this->mIsArticleRelated;
}
-
+
function getLanguageLinks() {
return $this->mLanguageLinks;
}
}
function getCategoryLinks() {
return $this->mCategoryLinks;
- }
+ }
function addCategoryLinks($newLinkArray) {
$this->mCategoryLinks += $newLinkArray;
}
function addWikiText( $text, $linestart = true, $cacheArticle = NULL )
{
global $wgParser, $wgParserCache, $wgUser, $wgTitle;
-
+
$parserOutput = $wgParser->parse( $text, $wgTitle, $this->mParserOptions, $linestart );
if ( $cacheArticle ) {
$wgParserCache->save( $parserOutput, $cacheArticle, $wgUser );
}
-
+
$this->mLanguageLinks += $parserOutput->getLanguageLinks();
$this->mCategoryLinks += $parserOutput->getCategoryLinks();
$this->addHTML( $parserOutput->getText() );
return false;
}
}
-
+
# Set the maximum cache time on the Squid in seconds
function setSquidMaxage( $maxage ) {
$this->mSquidMaxage = $maxage;
}
-
+
# Use enableClientCache(false) to force it to send nocache headers
function enableClientCache( $state ) {
return wfSetVar( $this->mEnableClientCache, $state );
}
-
+
function sendCacheControl() {
global $wgUseSquid, $wgUseESI;
# FIXME: This header may cause trouble with some versions of Internet Explorer
header( "Vary: Accept-Encoding, Cookie" );
if( $this->mEnableClientCache ) {
- if( $wgUseSquid && ! isset( $_COOKIE[ini_get( "session.name") ] ) &&
- ! $this->isPrintable() && $this->mSquidMaxage != 0 )
+ if( $wgUseSquid && ! isset( $_COOKIE[ini_get( "session.name") ] ) &&
+ ! $this->isPrintable() && $this->mSquidMaxage != 0 )
{
if ( $wgUseESI ) {
# We'll purge the proxy cache explicitly, but require end user agents
} else {
# We'll purge the proxy cache for anons explicitly, but require end user agents
# to revalidate against the proxy on each visit.
- # IMPORTANT! The Squid needs to replace the Cache-Control header with
+ # IMPORTANT! The Squid needs to replace the Cache-Control header with
# Cache-Control: s-maxage=0, must-revalidate, max-age=0
wfDebug( "** local proxy caching; {$this->mLastModified} **\n", false );
# start with a shorter timeout for initial testing
header( "Pragma: no-cache" );
}
}
-
+
# Finally, all the text has been munged and accumulated into
# the object, let's actually output it:
#
}
$fname = "OutputPage::output";
wfProfileIn( $fname );
-
+
$sk = $wgUser->getSkin();
if ( "" != $this->mRedirect ) {
}
$this->mLastModified = gmdate( "D, j M Y H:i:s" ) . " GMT";
}
-
+
$this->sendCacheControl();
-
+
if( $wgDebugRedirects ) {
$url = htmlspecialchars( $this->mRedirect );
print "<html>\n<head>\n<title>Redirect</title>\n</head>\n<body>\n";
}
return;
}
-
-
+
+
$this->sendCacheControl();
-
+
header( "Content-type: $wgMimeType; charset={$wgOutputEncoding}" );
header( "Content-language: {$wgLanguageCode}" );
foreach( $this->mCookies as $name => $val ) {
setcookie( $name, $val, $exp, "/" );
}
-
+
$sk->outputPage( $this );
# flush();
}
global $wgUser, $wgLang;
$wgInputEncoding = strtolower( $wgInputEncoding );
-
+
if( $wgUser->getOption( 'altencoding' ) ) {
$wgLang->setAltEncoding();
return;
$wgOutputEncoding = strtolower( $wgOutputEncoding );
return;
}
-
+
/*
# This code is unused anyway!
# Commenting out. --bv 2003-11-15
-
+
$a = explode( ",", $_SERVER['HTTP_ACCEPT_CHARSET'] );
$best = 0.0;
$bestset = "*";
$wgOutputEncoding = $wgInputEncoding;
}
- # Returns a HTML comment with the elapsed time since request.
+ # Returns a HTML comment with the elapsed time since request.
# This method has no side effects.
function reportTime()
{
list( $usec, $sec ) = explode( " ", $wgRequestTime );
$start = (float)$sec + (float)$usec;
$elapsed = $now - $start;
-
+
# Use real server name if available, so we know which machine
# in a server farm generated the current page.
if ( function_exists( "posix_uname" ) ) {
$this->mBodytext = "";
$sk = $wgUser->getSkin();
- $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" );
+ $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" );
$this->addHTML( wfMsg( "sysoptext", $ap ) );
$this->returnToMain();
}
$this->mBodytext = "";
$sk = $wgUser->getSkin();
- $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" );
+ $ap = $sk->makeKnownLink( wfMsg( "administrators" ), "" );
$this->addHTML( wfMsg( "developertext", $ap ) );
$this->returnToMain();
}
# We put a comment in the .html file so a Sysop can diagnose the page the
# user can't see.
- $this->addHTML( "\n<!--" .
- $wgLang->getNsText( $wgTitle->getNamespace() ) .
- ":" .
+ $this->addHTML( "\n<!--" .
+ $wgLang->getNsText( $wgTitle->getNamespace() ) .
+ ":" .
$wgTitle->getDBkey() . "-->" );
$this->returnToMain(); # Flip back to the main page after 10 seconds.
}
$msg = str_replace( "$2", htmlspecialchars( $fname ), $msg );
$msg = str_replace( "$3", $errno, $msg );
$msg = str_replace( "$4", htmlspecialchars( $error ), $msg );
-
+
if ( $wgCommandLineMode || !is_object( $wgUser )) {
print "$msg\n";
wfAbruptExit();
$reason = file_get_contents( $wgReadOnlyFile );
$this->addWikiText( wfMsg( "readonlytext", $reason ) );
}
-
+
if( is_string( $source ) ) {
if( strcmp( $source, "" ) == 0 ) {
$source = wfMsg( "noarticletext" );
htmlspecialchars( $source ) . "\n</textarea>";
$this->addHTML( $text );
}
-
+
$this->returnToMain( false );
}
function returnToMain( $auto = true, $returnto = NULL )
{
global $wgUser, $wgOut, $wgRequest;
-
+
if ( $returnto == NULL ) {
$returnto = $wgRequest->getText( 'returnto' );
}
"/[_]/" => ' '
);
$a = htmlspecialchars(preg_replace(array_keys($strip), array_values($strip),$a ));
-
+
$wgOut->addMeta ( "KEYWORDS" , $a ) ;
}
} else {
$ret = "";
}
-
+
$ret .= "<!DOCTYPE html PUBLIC \"$wgDocType\"\n \"$wgDTD\">\n";
if ( "" == $this->mHTMLtitle ) {
$ret .= "<html $xmlbits lang=\"$wgLanguageCode\" $rtl>\n";
$ret .= "<head>\n<title>" . htmlspecialchars( $this->mHTMLtitle ) . "</title>\n";
array_push( $this->mMetatags, array( "http:Content-type", "$wgMimeType; charset={$wgOutputEncoding}" ) );
-
+
$ret .= $this->getHeadLinks();
global $wgStylePath;
if( $this->isPrintable() ) {
$ret .= "</head>\n";
return $ret;
}
-
+
function getHeadLinks() {
global $wgRequest, $wgStylePath;
$ret = "";